package com.shukesmart.speech.ui.notifications;

import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_MEDIA_AUDIO;
import static android.Manifest.permission.READ_MEDIA_VIDEO;
import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioTrack;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.shukesmart.skspeech.CloudTTSListener;
import com.shukesmart.skspeech.SKSSLHelper;
import com.shukesmart.skspeech.SKSpeechListener;
import com.shukesmart.skspeech.SKSpeechRecognize;
import com.shukesmart.speech.R;
import com.shukesmart.speech.databinding.FragmentHomeBinding;
import com.shukesmart.speech.databinding.FragmentNotificationsBinding;
import com.shukesmart.speech.ui.home.HomeViewModel;
import com.shukesmart.speech.utils.AudioPlayer;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;

import io.reactivex.disposables.Disposable;

public class NotificationsFragment extends  Fragment {
    String TAG = "HomeFragment";
    long startTime;
    TextView textview;
    TextView languageText;
    TextView translateText;
    TextView textview_origin_tag;
    TextView translate;
    Button start_record;
    Button stop_record;
    private volatile boolean isRunning = false;
    private InputStream is = null;
    SKSpeechRecognize skSpeechRecognize;
    private int translateselectedNum = 119;
    private int currentLanguage =26 ;
    String fileName = "tts.pcm";
    LinearLayout relativeLayout;
    private static final int PERMISSION_REQUEST_CODE = 1;
    private Disposable subscription;
    private FragmentNotificationsBinding binding;
    private String[] languageEntries;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        NotificationsViewModel homeViewModel =
                new ViewModelProvider(this).get(NotificationsViewModel.class);

        binding = FragmentNotificationsBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        //创建目录
        String dir = SKSSLHelper.getSDCardPrivateCacheDir(requireActivity());
        File folder = new File(dir + "/skspeechrecognizeTest");
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File file = new File(folder + File.separator + fileName);
        if (file.exists()) {
            file.delete();
        }


        languageEntries = getResources().getStringArray(R.array.translate_language_entries);

        languageText = binding.languageText;
        translateText = binding.translateText;

        languageText.setOnClickListener(this::setLanguage);
        translateText.setOnClickListener(this::setTranslateLanguage);


        start_record = binding.startRecord;
        textview = binding.textviewOrigin;
        translate = binding.textviewTranslate;
        relativeLayout = binding.relativeLayout;

        //初始化

        initSpeechRecognizer();
        start_record.setOnClickListener(v -> {

            // 麦克风
            if (!isRunning) {
                isRunning = true;
                stop_record.setVisibility(Button.VISIBLE);
                start_record.setVisibility(ImageView.INVISIBLE);
                textview.setText("");
                translate.setText("");
                try {
                    this.skSpeechRecognize.startRealTimeRecorder(requireActivity());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                Toast.makeText(requireActivity(), "正在录音中，请稍后再试", Toast.LENGTH_SHORT).show();
            }
        });

        // 停止录音
        stop_record = binding.stopRecord;
        stop_record.setOnClickListener(v -> {
            stop_record.setVisibility(Button.INVISIBLE);
            start_record.setVisibility(ImageView.INVISIBLE);
            try {
                this.skSpeechRecognize.stopRealTimeRecorder();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }


        });

        //homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
        return root;
    }

    @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
    private boolean checkPermission() {
        return ContextCompat.checkSelfPermission(requireActivity(), RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(requireActivity(), INTERNET) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(requireActivity(), READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(requireActivity(), READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(requireActivity(), READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(requireActivity(), WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 权限被用户同意，可以执行相关操作
            } else {
                // 权限被用户拒绝，需要进一步操作，比如引导用户去设置页面开启权限
            }
        }
    }

    private byte[] bytes_append(byte[] a, byte[] b) {
        byte[] c = new byte[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

    void translate() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //云端tts
                try {
                    SKSpeechRecognize.translate(requireActivity(), "8ff895c1328f11efb151931bd7bb0df3", "c637dwfee475dsfwb09de4", 119, 26, " 今天天气很好", "female", "audio/pcm", 192, 10, new CloudTTSListener() {
                        @Override
                        public void CloudTTSSuccess(byte[] result) {
                            Log.i(TAG, "CloudTTSSuccess: " + Arrays.toString(result));
                            int bufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
                            AudioPlayer audioPlayer = new AudioPlayer(16000, false, bufferSize);
                            audioPlayer.playAudio(result);
                            audioPlayer.stopPlaying();
                        }

                        @Override
                        public void CloudTTSError(String error, int code) {
                            Log.e(TAG, "CloudTTSError: " + error + " " + code);

                        }

                        @Override
                        public void CloudTranslateSuccess(JSONObject result) {
                            Log.i(TAG, "CloudTranslateSuccess: " + result.toString());

                        }
                    });
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();
    }

    void CreaeCloudTTS() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //云端tts
                try {
                    SKSpeechRecognize.cloudTTS(requireActivity(), "8ff895c1328f11efb151931bd7bb0df3", "c637dwfee475dsfwb09de4", 26, "female", "audio/pcm", "Hello, my name is james, and I come from a vibrant city where the culture is as diverse as its people. I currently reside in the heart of this city, where the hustle and bustle of daily life never ceases to amaze me.My journey in life has been a colorful tapestry of experiences", new CloudTTSListener() {
                        @Override
                        public void CloudTTSSuccess(byte[] result) {
//                            int sampleRate = 16000; // 取决于你的音频流的采样率
//                            boolean isStereo = false; // 是否为立体声
//                            int bufferSize = AudioTrack.getMinBufferSize(sampleRate, isStereo ? AudioFormat.CHANNEL_OUT_STEREO : AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
//
//                            AudioPlayer audioPlayer = new AudioPlayer(sampleRate, isStereo, bufferSize);
//                            folder + File.separator + fileName
//                            audioPlayer.play();
//                            audioPlayer.stopPlaying();
                        }

                        @Override
                        public void CloudTTSError(String error, int code) {

                        }

                        @Override
                        public void CloudTranslateSuccess(JSONObject jsonObject) {

                        }
                    });
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();
    }

    private byte[] get16BitPcm(short[] data) {
        byte[] resultData = new byte[2 * data.length];
        int iter = 0;

        String TAG = "get16BitPcm";
        for (short sample : data) {
            resultData[iter++] = (byte) (sample & 0xff);     //低位存储，0xff是掩码操作
            resultData[iter++] = (byte) ((sample >> 8) & 0xff); //高位存储

        }
        return resultData;
    }

    //创建目录
    final Handler cwjHandler = new Handler();

    final Runnable mUpdateResults = new Runnable() {
        public void run() {
            Log.i(TAG, "run:time=" + (System.currentTimeMillis() - startTime));
            stop_record.setVisibility(Button.INVISIBLE);
            start_record.setVisibility(ImageView.VISIBLE);
            relativeLayout.removeAllViews();
        }
    };

    private void initSpeechRecognizer() {
        //初始化
        Handler handler = new Handler(Looper.getMainLooper());

        try {
            SKSpeechRecognize.setPrintLog(true);
            skSpeechRecognize = SKSpeechRecognize.createRecognizer(requireActivity(), "bb7b4c5122f011ef8acfedca1adaee2b", "c637dwfee475dsfwb09de4", "shukesmart");
            if (null == skSpeechRecognize) {
                // 创建失败
                Toast.makeText(requireActivity(), "创建对象失败， createRecognizer 进行初始化", Toast.LENGTH_SHORT).show();
                return;
            }
            skSpeechRecognize.setSkSpeechListener(
                    new SKSpeechListener() {
                        @Override
                        public void onInit(boolean isSuccess, String msg) {
                        }

                        @Override
                        public void onBegin() {
                            Log.i(TAG, "onBegin: ");

                        }

                        @Override
                        public void onCompleted(int code) throws IOException {
                            Log.i(TAG, "onCompleted: " + code);

                            isRunning = false;
                            cwjHandler.post(mUpdateResults); //高速UI线程可以更新结果了
                        }

                        @Override
                        public void onError(String msg) {

                        }

                        @Override
                        public void onAsrResult(boolean isFinal, String result) {


                            handler.post(new Runnable() {
                                @Override
                                public void run() {


                                    if (isFinal) {

                                        TextView textView = new TextView(requireActivity());
                                        textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

                                        textView.setTextSize(16);

                                        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) textView.getLayoutParams();
                                        lp.setMargins(0, 16, 0, 10);
                                        textView.setLayoutParams(lp);
                                        textView.setText(result);
                                        // 添加到LinearLayout
                                        relativeLayout.addView(textView);
                                        textview.setText("");
                                    } else {
                                        textview.setText(result);
                                    }
                                }
                            });


                        }

                        @Override
                        public void onTraslateResult(boolean isFinal, String result) {
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (isFinal) {

                                        //  translate.setText(t1);
                                        TextView textView = new TextView(requireActivity());
                                        textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

                                        textView.setTextSize(16);
                                        textView.layout(0, 16, 0, 0);

                                        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) textView.getLayoutParams();
                                        lp.setMargins(0, 10, 0, 0);
                                        textView.setLayoutParams(lp);
                                        textView.setText(result);
                                        translate.setText("");

                                        // 添加到LinearLayout
                                        relativeLayout.addView(textView);

                                    } else {

                                        translate.setText(result);

                                    }

                                }
                            });


                        }

                        @Override
                        public void onTTSResult(byte[] result) {

                            Log.i(TAG, "onTTSResult: " + Arrays.toString(result));

                        }

                        @Override
                        public void onAsrEnd(String allResult) {
                            Log.i(TAG, "onAsrEnd: " + allResult);
                        }

                        @Override
                        public void onTraslateEnd(String allResult) {
                            Log.i(TAG, "onTraslateEnd: " + allResult);
                        }

                        @Override
                        public void onTTSEnd(byte[] result) {
                            Log.i(TAG, "onTTSEnd: " + Arrays.toString(result));
                        }

                        @Override
                        public void onFlushChunk() {
                            Log.i(TAG, "onFlushChunk: ");
                        }
                    });
                                skSpeechRecognize.setSocketUrl("mb.asr.cloudspeech.sinicloud.com");
                    skSpeechRecognize.setSocketPort(16905);
            boolean set_ret = skSpeechRecognize.setParameter(2, currentLanguage ,translateselectedNum, 16000, 1, AudioFormat.ENCODING_PCM_16BIT, "female", true);
            skSpeechRecognize.setGisOpenAutoPlay(true);

            if (!set_ret) {
                System.out.println("set failed");

            }
        } catch (ExecutionException | InterruptedException | IOException |
                 NoSuchAlgorithmException | CertificateException |
                 UnrecoverableKeyException |
                 KeyStoreException | KeyManagementException e) {
            throw new RuntimeException(e);
        }

    }

    private void setLanguage(View v) {
        if(isRunning){
            Toast.makeText(requireActivity(), "正在录音中，无法修改语种", Toast.LENGTH_SHORT).show();
            return;
        }
        new AlertDialog.Builder(v.getContext()).setTitle("语音识别语言种类")
                .setSingleChoiceItems(languageEntries, // 单选框有几项,各是什么名字
                        currentLanguage-1, // 默认的选项
                        new DialogInterface.OnClickListener() { // 点击单选框后的处理
                            public void onClick(DialogInterface dialog,
                                                int which) { // 点击了哪一项
                                currentLanguage = which+1;
                                languageText.setText(languageEntries[which]);
                                boolean set_ret = false;
                                try {
                                    set_ret = skSpeechRecognize.setParameter(2, currentLanguage, translateselectedNum, 16000, 1, AudioFormat.ENCODING_PCM_16BIT, "female", true);
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }

                                if (!set_ret) {
                                    System.out.println("set failed");

                                }
                                dialog.dismiss();
                            }
                        }).show();
    }

    private void setTranslateLanguage(View v) {
        if(isRunning){
            Toast.makeText(requireActivity(), "正在录音中，无法修改语种", Toast.LENGTH_SHORT).show();
            return;
        }
        new AlertDialog.Builder(v.getContext()).setTitle("翻译语种")
                .setSingleChoiceItems(languageEntries, // 单选框有几项,各是什么名字
                        translateselectedNum-1, // 默认的选项
                        new DialogInterface.OnClickListener() { // 点击单选框后的处理
                            public void onClick(DialogInterface dialog,
                                                int which) { // 点击了哪一项
                                translateselectedNum = which+1;
                                translateText.setText(languageEntries[which]);
                                boolean set_ret = false;
                                try {
                                    set_ret = skSpeechRecognize.setParameter(2, currentLanguage, translateselectedNum, 16000, 1, AudioFormat.ENCODING_PCM_16BIT, "female", true);
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }

                                if (!set_ret) {
                                    System.out.println("set failed");

                                }
                                dialog.dismiss();
                            }
                        }).show();
    }

    short[] byteToShortArray(byte[] bytes) {
        short[] shorts = new short[bytes.length / 2];
        ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        return shorts;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    skSpeechRecognize.stopRealTimeRecorder();
                    skSpeechRecognize.closeSpeech();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

}